//
//  Utils_Swizzing.m
//  TravelGuideMdd
//
//  Created by 陈曦 on 13-8-2.
//  Copyright (c) 2013年 mafengwo.com. All rights reserved.
//

#import "Utils_Swizzing.h"
#import <objc/runtime.h>
#import <objc/message.h>

void* objc_changeMethod_Plus(Class class,
                              SEL sel,
                              void *newFunction,
                              BOOL *addOrReplace)
{
    Method oldMethod = class_getInstanceMethod(class, sel);

    void* oldFuction = (void*)method_getImplementation(oldMethod);
    BOOL succeed = class_addMethod(class,
                                   sel,
                                   (IMP)newFunction,
                                   method_getTypeEncoding(oldMethod));
    if (oldMethod && succeed)
    {
        oldFuction = nil;
    }

    if (addOrReplace)
    {
        *addOrReplace = succeed;
    }
    if (!succeed)
    {
        oldFuction = method_setImplementation(oldMethod, (IMP)newFunction);
    }
    return oldFuction;
}

void* objc_changeMethod(Class class,
                        SEL sel,
                        void *newFunction)
{
    return objc_changeMethod_Plus(class,
                                   sel,
                                   newFunction, nil);
}



void* objc_changeClassMethod_Plus(Class class,
                                   SEL sel,
                                   void*newFunction,
                                   BOOL *addOrReplace)
{
    Method oldMethod = class_getClassMethod(class, sel);
    void* oldFuction = (void*)method_getImplementation(oldMethod);
    class = object_getClass((id)class);

    BOOL succeed = class_addMethod(class,
                                   sel,
                                   (IMP)newFunction,
                                   method_getTypeEncoding(oldMethod));
    if (addOrReplace)
    {
        *addOrReplace = succeed;
    }
    if (!succeed)
    {
        method_setImplementation(oldMethod, (IMP)newFunction);
    }
    return oldFuction;
}

void* objc_changeClassMethod(Class class,
                             SEL sel,
                             void*newFunction)
{
    return objc_changeClassMethod_Plus(class,sel, newFunction, nil);
}
